
import cv2
import face_recognition as fr
import mediapipe as mp
import keyboard
import global_variable as gl
import face_recogn as FaceR
from face_recogn import FaceThread
from gesture_recogn import HandThread
from transmit_inform import ShowThread




#通信传输#####################################################################################################
# global myRaspConnection
# myRaspConnection = myclient.connect_Raspberry('120.46.171.197', 8888)
#gl.RaspInit()
#############################################################################################################
Face_Data = "./data" #人脸数据集
#############################################################################################################
gl.flag_init()
gl.dec_init()
gl.identify_init()
gl.hand_queue_init()
gl.face_queue_init()
#############################################################################################################
#手势画线
class handDetector():
    def __init__(self, mode=False, maxHands=2, complexity=1, detectionCon=0.5, trackCon=0.5):
        # 初始化类的参数
        self.mode = mode
        self.maxHands = maxHands
        self.complexity = complexity
        self.detectionCon = detectionCon
        self.trackCon = trackCon

        # 初始化手跟踪模块
        self.mpHands = mp.solutions.hands
        # mediapipe version: 0.8.11
        self.hands = self.mpHands.Hands(self.mode, self.maxHands, self.complexity,
                                        self.detectionCon, self.trackCon)
        # mediapipe version: 0.8.3
        # self.hands = self.mpHands.Hands(self.mode, self.maxHands,
        #                                 self.detectionCon, self.trackCon)
        self.mpDraw = mp.solutions.drawing_utils

    # 跟踪手关节点位置
    def findHands(self, img, draw=True):
        imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        self.results = self.hands.process(imgRGB)

        if self.results.multi_hand_landmarks:
            for handLms in self.results.multi_hand_landmarks:
                if draw:
                    self.mpDraw.draw_landmarks(img, handLms,
                                               self.mpHands.HAND_CONNECTIONS)
        return img

    # 对手关节点绘制圆圈
    def findPostion(self, img, handNo=0, draw=True):
        lmList = []
        if self.results.multi_hand_landmarks:
            for myHand in self.results.multi_hand_landmarks:
                for id, lm in enumerate(myHand.landmark):
                    h, w, c = img.shape
                    cx, cy = int(lm.x * w), int(lm.y * h)
                    lmList.append([id, cx, cy])
                    if draw:
                        cv2.circle(img, (cx, cy), 12, (255, 0, 255), cv2.FILLED)
        return lmList


def CatchUsbVideo(window_name, camera_idx):
    cv2.namedWindow(window_name)
    # 视频来源，可以来自一段已存好的视频，也可以直接来自USB摄像头
    cap = cv2.VideoCapture(camera_idx)
    ind = 0
    fre = 5
    ImageName = ["None","Unknow","Unknow","Unknow","0"]
    t1 = FaceThread(1)
    t1.start()
    t2 = HandThread(2)
    t2.start()
    t3 = ShowThread(3)
    t3.start()
    last_cen_x = 400
    last_cen_y = 300
    detector = handDetector()
    while cap.isOpened():
        #ok, frame = cap.read()  # 读取一帧数据
        ind = ind+1
        if ind >= 1000000 :
            ind = 1
        ok = cap.grab()
        if not ok:
            break
        #frame = cv2.flip(frame, -1)
        if ind % fre == 0:
            ok, frame = cap.retrieve()

            #lmList = detector.findPostion(frame)
            if frame is None:
                break
            if gl.get_hand_image().empty():
                gl.put_hand_image(frame)
                gl.put_hand_image(frame)
            #IMG = detector.findHands(frame) #手势画线
            change_img = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
            frame_RGB = change_img[:, :, ::-1]
            # 将当前帧转换成灰度图像
            faces_locations = fr.face_locations(frame_RGB)

            if gl.get_face_image().empty():
                gl.put_face_image(frame_RGB)
                gl.put_face_image(frame_RGB)

            global x0, y0, x1, y1
            fg = True
            for (top, right, bottom, left) in faces_locations:
                #print("into for")
                top *= 4
                right *= 4
                bottom *= 4
                left *= 4
                if fg:
                    # print(top,left,bottom,right)
                    y0 = top
                    x0 = left
                    y1 = bottom
                    x1 = right
                    fg = False

                if not gl.get_identify().empty():
                    ImageName = gl.pop_identify()
                # print(ImageName)
                ##此处注释为显示参数于显示屏
                cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)

                cv2.putText(frame, ImageName[1],
                            (0,40),  # 坐标
                            cv2.FONT_HERSHEY_SIMPLEX,  # 字体
                            0.8,  # 字号
                            (0, 255, 0),  # 颜色
                            2)
                # cv2.putText(frame, ImageName[1],
                #             (left, top-5),  # 坐标
                #             cv2.FONT_HERSHEY_SIMPLEX,  # 字体
                #             0.8,  # 字号
                #             (0, 255, 0),  # 颜色
                #             2)
                cv2.putText(frame, ImageName[2],
                            (0,65),  # 坐标
                            cv2.FONT_HERSHEY_SIMPLEX,  # 字体
                            0.8,  # 字号
                            (0, 255, 0),  # 颜色
                            2)
                # cv2.putText(frame, ImageName[3],
                #             (0,90),  # 坐标
                #             cv2.FONT_HERSHEY_SIMPLEX,  # 字体
                #             0.8,  # 字号./m
                #             (0,255, 0),  # 颜色
                #             2)
                # cv2.putText(frame, ImageName[4],
                #             (0,115),  # 坐标
                #             cv2.FONT_HERSHEY_SIMPLEX,  # 字体
                #             0.8,  # 字号
                #             (255, 0, 0),  # 颜色
                #             2)
                cur_x = (x0 + x1) / 2
                cur_y = (y0 + y1) / 2
                #坐标标注
                # textstr = "x:"
                # textstr+=str(cur_x)
                # textstr+=" "
                # textstr+="y:"
                # textstr+=str(cur_y)
                # cv2.putText(frame,textstr,
                # (left, top),  # 坐标
                # cv2.FONT_HERSHEY_SIMPLEX,  # 字体
                # 0.8,  # 字号
                # (225, 125, 125),  # 颜色
                # 2)
                #发送数据
                # if cur_x - last_cen_x >= 15 or cur_y - last_cen_y >= 15:
                #     # print(cur_x, cur_y)
                #     last_cen_x = cur_x
                #     last_cen_y = cur_y
                msg = "1_"
                msg += str(gl.get_dec())
                msg += "_"
                msg += str(int(cur_x)) + "_" + str(int(cur_y))+"#"
                gl.Get_Rasp().send(msg)
                #print(msg)
        # 显示图像
            cv2.imshow(window_name, frame)
            c = cv2.waitKey(5)#每一帧的持续时间ms
            if keyboard.is_pressed('q'):
                mag = "1_0_0_65535#"
                print(mag)
                gl.Get_Rasp().send(mag)
                mag = "0_1_0_65535#"
                gl.Get_Rasp().send(mag)
                print(mag)
                gl.flag_set(False)
                break
    # 释放摄像头并销毁所有窗口
    t1.join()
    t2.join()
    t3.join()
    cap.release()
    cv2.destroyAllWindows()


if __name__ == '__main__':
        FaceR.ReadJPG(Face_Data)
        CatchUsbVideo("Identity Display", "http://192.168.8.9:8081")

